package cn.skyclass.net
{
	import cn.skyclass.beans.IUploadFileBean;
	import cn.skyclass.controls.AdvancedAlert;
	import cn.skyclass.events.GlobalTipEvent;
	import cn.skyclass.utils.SizeFormatter;
	
	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.FileReference;
	import flash.net.URLRequest;

	/**
	 * 文件的创建者，完成一个客户端物理文件的浏览和上传工作
	 */
	[Bindable]
	[Event(name="progress", type="flash.events.ProgressEvent")]
	[Event(name="uploadCompleteData", type="flash.events.DataEvent")]
	public class FileCreator extends BaseSubmitter
	{
		/**
		 * @fileBean : 存储浏览到的文件信息的实例
		 * @uploadUrl : 接收文件的服务器端的 url
		 * 		eg: http://192.168.1.21:8080/website1/fileupload
		 */
		public function FileCreator(fileBean:IUploadFileBean=null, uploadUrl:String=null){
			this.fileBean = fileBean;
			this.uploadUrl = uploadUrl;
			
			this.fileRef = new FileReference();
			this.fileRef.addEventListener(Event.SELECT, this.fileSelectdHandler);
			this.fileRef.addEventListener(Event.COMPLETE, this.uploadCompleteHandler);
			this.fileRef.addEventListener(IOErrorEvent.IO_ERROR, this.uploadFailedHandler);
			this.fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.relayFileReferenceEvent);
			this.fileRef.addEventListener(ProgressEvent.PROGRESS, this.relayFileReferenceEvent);	
		}
		
		/**
		 * 是否限制文件的大小 以及 上传文件的最大比特值
		 */ 
		public var limitSize:Boolean = false;
		public var maxUploadSize:Number = 50 * 1024 * 1024; // 50MB
		
		/**
		 * 是否存在需要上传的文件。如果当前选中的文件已经上传，此值将被重置为 false
		 */
		public var hasFileForUpload:Boolean;
		
		/**
		 * 是否有文件，如果用户浏览到了正确的文件，此值将一直为 true
		 */
		public var hasFile:Boolean;
		
		/**
		 * 存储浏览到的文件信息的实例
		 */
		protected var fileBean:IUploadFileBean;
		
		/**
		 * 接收文件的服务器端的 url
		 * eg: http://192.168.1.21:8080/website1/fileupload
		 */
		protected var uploadUrl:String;
		
		protected var fileRef:FileReference;
		private var urlReq:URLRequest;

		/**
		 * 开始浏览文件
		 */
		public function browse(typeFilter:Array=null):Boolean{
			return this.fileRef.browse(typeFilter);
		}
		
		/**
		 * 取消文件的上传
		 */
		public function cancelUpload():void{
			this.fileRef.cancel();
			this.uploadFailedHandler();
		}
				
		/**
		 * 返回选中的文件是否合法
		 */		
		protected function fileSelectdHandler(e:Event):Boolean{
			if(this.limitSize && (this.fileRef.size > this.maxUploadSize)){
				// 选中的文件无效，不做任何处理
				var msg:String = "允许上传的最大文件大小为: ";
				msg += SizeFormatter.format(this.maxUploadSize);
				AdvancedAlert.info(msg);
				return false;
			}else{
				this.hasFile = true;
				this.hasFileForUpload = true;
				this.fileBean.setPropertiesWithRef(this.fileRef);
				return true;
			}
		}	
			
		override protected function doSubmit():void{
			uploadFile();
		}
		
		/**
		 * 开始执行文件的上传
		 */
		protected function uploadFile():void{
			if(!this.hasFileForUpload){
				this.uploadCompleteHandler(); return;
			}
			
			this.urlReq = new URLRequest();		
			this.urlReq.url = this.getFullUploadUrl();

			this.en.dispatchEvent(
				new GlobalTipEvent(GlobalTipEvent.START_TIP, "Uploading file"));
			this.fileRef.upload(urlReq);		
		}
		
		/**
		 * 获取上传文件的完整 url 路径
		 */
		protected function getFullUploadUrl():String{
			return this.uploadUrl + "?filename=" + this.fileBean.guidFileName;
		}
		
		protected function uploadCompleteHandler(e:Event=null):void{
			this.fileBean.uploadedNewFile = this.hasFile;
			this.endFileUpload(true);
		}	
		
		protected function uploadFailedHandler(e:Event=null):void{
			this.fileBean.uploadedNewFile = false;
			this.endFileUpload(false);
		}			
		
		/**
		 * 结束文件的上传工作
		 */
		protected function endFileUpload(successful:Boolean=true):void{
			this.hasFileForUpload = !successful;
			
			this.en.dispatchEvent(new GlobalTipEvent(GlobalTipEvent.END_TIP));
			if(!successful){
				this.en.dispatchEvent(
					new GlobalTipEvent(GlobalTipEvent.TEMP_TIP, "Upload failed!"));
			}
		}	

		protected function relayFileReferenceEvent(e:Event):void{
			dispatchEvent(e);
		}
		
	}
}